from FacileCalGUI_Main import *
from math import log,pow,atan,cos,sin,sqrt

pi=3.1415926

def significant_digits(x,dig=3):
    if isinstance(x,list):
        temp = []
        for i in x:
            temp.append(round(i,dig))
        return temp
    elif isinstance(x,float):
        return round(x,dig)

class mainProgram(QtWidgets.QMainWindow, Ui_Facile_Calculator):
    def __init__(self, parent=None):
        super(mainProgram, self).__init__(parent)
        self.setupUi(self)
        self.Btn_Gamma_Real_Imag.clicked.connect(self.gamma_re_im_to_others)
        self.lineEdit_Gamma_Real.returnPressed.connect(self.gamma_re_im_to_others)
        self.lineEdit_Gamma_Imag.returnPressed.connect(self.gamma_re_im_to_others)
        self.Btn_Gamma_Amp_Phi.clicked.connect(self.gamma_amp_phi_to_others)
        self.lineEdit_Gamma_Amp.returnPressed.connect(self.gamma_amp_phi_to_others)
        self.lineEdit_Gamma_Phi.returnPressed.connect(self.gamma_amp_phi_to_others)
        self.Btn_Impedance.clicked.connect(self.impedance_to_gamma)
        self.lineEdit_Impe_Real.returnPressed.connect(self.impedance_to_gamma)
        self.lineEdit_Impe_Imag.returnPressed.connect(self.impedance_to_gamma)
        self.Btn_Wavelength.clicked.connect(self.wavelength_to_frequency)
        self.lineEdit_Wavelength.returnPressed.connect(self.wavelength_to_frequency)
        self.Btn_Frequency.clicked.connect(self.frequency_to_wavelength)
        self.lineEdit_Frequency.returnPressed.connect(self.frequency_to_wavelength)
        self.Btn_dbm.clicked.connect(self.dB_to_abs)
        self.lineEdit_dbm.returnPressed.connect(self.dB_to_abs)
        self.Btn_mW.clicked.connect(self.abs_to_dB)
        self.lineEdit_mW.returnPressed.connect(self.abs_to_dB)
        self.Btn_S21.clicked.connect(self.S21_to_through)
        self.lineEdit_S21.returnPressed.connect(self.S21_to_through)
        self.Btn_Through.clicked.connect(self.through_to_S21)
        self.lineEdit_Through.returnPressed.connect(self.through_to_S21)

        self.Btn_nsh.clicked.connect(self.calculate_nsh_of_Rsh)
        self.Btn_mobility.clicked.connect(self.calculate_mob_of_Rsh)
        self.Btn_Rsh.clicked.connect(self.calculate_Rsh_of_Rsh)
        self.Btn_nsh2.clicked.connect(self.calculate_nsh2_of_I)
        self.Btn_vdrift.clicked.connect(self.calculate_vd_of_I)
        self.Btn_current.clicked.connect(self.calculate_I_of_I)
        self.Btn_LG.clicked.connect(self.calculate_LG_of_fT)
        self.Btn_fT.clicked.connect(self.calculate_fT_of_fT)
        self.Btn_vtrans.clicked.connect(self.calculate_vt_of_fT)
        self.Btn_Rshunt.clicked.connect(self.calculate_shunt_resistance)

        self.lineEdit_Rshunt.returnPressed.connect(self.calculate_shunt_resistance)


    def get_z0(self):
        if self.radioButton_50ohm.isChecked():
            z0 = 50
        elif self.radioButton_100ohm.isChecked():
            z0 = 100
        elif self.radioButton_1086ohm.isChecked():
            z0 = 1086
        return z0

    def get_servant_para_from_gamma_amp(self,gamma_amp):
        pw_reflected = pow(gamma_amp, 2) * 100
        pw_reflected = significant_digits(pw_reflected, 2)
        self.textBrowser_Preflected.setText(str(pw_reflected))
        if gamma_amp == 0:
            self.textBrowser_S11.setText("-∞")
        else:
            s11 = 10 * log(gamma_amp, 10)
            s11 = significant_digits(s11, 2)
            self.textBrowser_S11.setText(str(s11))
        if gamma_amp == 1:
            self.textBrowser_VSWR.setText("+∞")
        else:
            vswr = (1 + gamma_amp) / (1 - gamma_amp)
            vswr = significant_digits(vswr, 1)
            self.textBrowser_VSWR.setText(str(vswr))

    def gamma_re_im_to_others(self):
        # try:
            gamma_re = float(self.lineEdit_Gamma_Real.text())
            gamma_im = float(self.lineEdit_Gamma_Imag.text())
            gamma = complex(gamma_re, gamma_im)

            gamma_amp = gamma.__abs__()
            gamma_amp = round(gamma_amp, 3)

            if gamma_amp == 0:
                gamma_phi = 0
            else:
                gamma_phi = atan(gamma.imag / gamma.real)
                gamma_phi = 360 * gamma_phi / (2 * 3.1415926)
                gamma_phi = significant_digits(gamma_phi,2)
            self.lineEdit_Gamma_Amp.setText(str(gamma_amp))
            self.lineEdit_Gamma_Phi.setText(str(gamma_phi))

            z0=self.get_z0()

            if gamma==1:
                self.lineEdit_Impe_Real.setText("+∞")
            else:
                imp = z0*(1+gamma)/(1-gamma)
                [imp_re,imp_im]=significant_digits([imp.real,imp.imag])
                self.lineEdit_Impe_Real.setText(str(imp_re))
                self.lineEdit_Impe_Imag.setText(str(imp_im))

            self.get_servant_para_from_gamma_amp(gamma_amp)

        # except:
        #     self.lineEdit_Gamma_Real.setText("0")
        #     self.lineEdit_Gamma_Imag.setText("0")

    def gamma_amp_phi_to_others(self):
        # try:
            gamma_amp = float(self.lineEdit_Gamma_Amp.text())
            gamma_phi = float(self.lineEdit_Gamma_Phi.text())
            gamma_re = cos(2*3.1415926*gamma_phi/360) * gamma_amp
            gamma_im = sin(2*3.1415926*gamma_phi/360) * gamma_amp
            gamma = complex(gamma_re, gamma_im)
            gamma_re, gamma_im = significant_digits([gamma_re, gamma_im])

            self.lineEdit_Gamma_Real.setText(str(gamma_re))
            self.lineEdit_Gamma_Imag.setText(str(gamma_im))

            z0=self.get_z0()

            if gamma == 1:
                self.lineEdit_Impe_Real.setText("+∞")
            else:
                imp = z0 * (1 + gamma) / (1 - gamma)
                imp_re,imp_im = significant_digits([imp.real,imp.imag])
                self.lineEdit_Impe_Real.setText(str(imp_re))
                self.lineEdit_Impe_Imag.setText(str(imp_im))

            self.get_servant_para_from_gamma_amp(gamma_amp)
        # except:
        #     self.lineEdit_Gamma_Real.setText("0")
        #     self.lineEdit_Gamma_Imag.setText("0")

    def impedance_to_gamma(self):
        # try:
            imp_re=float(self.lineEdit_Impe_Real.text())
            imp_im=float(self.lineEdit_Impe_Imag.text())
            imp=complex(imp_re,imp_im)

            z0=self.get_z0()

            gamma=(imp-z0)/(imp+z0)
            gamma_amp=gamma.__abs__()
            gamma_re,gamma_im,gamma_amp=significant_digits([gamma.real,gamma.imag,gamma_amp])

            if gamma_amp==0:
                gamma_phi=0
            else:
                gamma_phi=atan(gamma.imag/gamma.real)
                gamma_phi=360*gamma_phi/(2*3.1415926)
                gamma_phi=round(gamma_phi,2)

            self.lineEdit_Gamma_Real.setText(str(gamma_re))
            self.lineEdit_Gamma_Imag.setText(str(gamma_im))
            self.lineEdit_Gamma_Amp.setText(str(gamma_amp))
            self.lineEdit_Gamma_Phi.setText(str(gamma_phi))

            self.get_servant_para_from_gamma_amp(gamma_amp)
        # except:
        #     self.lineEdit_Impe_Real.setText("50")
        #     self.lineEdit_Impe_Imag.setText("0")

    def wavelength_to_frequency(self):
        try:
            wavelength=float(self.lineEdit_Wavelength.text())
            f=round(1E-9*3E8/(wavelength*0.01),2)
            self.lineEdit_Frequency.setText(str(f))
        except:
            self.lineEdit_Wavelength.setText("1")

    def frequency_to_wavelength(self):
        try:
            f=float(self.lineEdit_Frequency.text())
            wavelength=round(1E2*3E8/(f*1E9),2)
            self.lineEdit_Wavelength.setText(str(wavelength))
        except:
            self.lineEdit_Frequency.setText("1")

    def abs_to_dB(self):
        try:
            abs=float(self.lineEdit_mW.text())
            dB=10*log(abs,10)
            dB=significant_digits(dB,2)
            self.lineEdit_dbm.setText(str(dB))
        except:
            self.lineEdit_dbm.setText("1")

    def dB_to_abs(self):
        try:
            dB=float(self.lineEdit_dbm.text())
            abs=pow(10,dB/10)
            abs=significant_digits(abs,2)
            self.lineEdit_mW.setText(str(abs))
        except:
            self.lineEdit_mW.setText("1")

    def S21_to_through(self):
        try:
            S21=float(self.lineEdit_S21.text())
            through=pow(10,S21/10)*100
            # through=pow(10,S21/10)*pow(10,S21/10)*100
            through=significant_digits(through,2)
            self.lineEdit_Through.setText(str(through))
        except:
            self.lineEdit_Through.setText("100")

    def through_to_S21(self):
        try:
            through=float(self.lineEdit_Through.text())
            S21=10*log(sqrt(through/100),10)
            S21=significant_digits(S21,2)
            self.lineEdit_S21.setText(str(S21))
        except:
            self.lineEdit_S21.setText("0")

    def calculate_nsh_of_Rsh(self):
        try:
            mob=float(self.lineEdit_mobility.text())
            Rsh=float(self.lineEdit_Rsh.text())
            nsh=(1/Rsh)/(mob*1.6E-19)
            nsh=significant_digits(nsh,2)
            nsh= "%.2e"%(nsh)
            self.lineEdit_nsh.setText(str(nsh))
        except:
            self.lineEdit_nsh.setText("0")

    def calculate_mob_of_Rsh(self):
        try:
            Rsh=float(self.lineEdit_Rsh.text())
            nsh=float(self.lineEdit_nsh.text())
            mob=(1/Rsh)/(nsh*1.6E-19)
            mob=significant_digits(mob,1)
            self.lineEdit_mobility.setText(str(mob))
        except:
            self.lineEdit_mobility.setText("0")

    def calculate_Rsh_of_Rsh(self):
        try:
            mob=float(self.lineEdit_mobility.text())
            nsh=float(self.lineEdit_nsh.text())
            Rsh=1/(mob*nsh*1.6E-19)
            Rsh=significant_digits(Rsh,1)
            self.lineEdit_Rsh.setText(str(Rsh))
        except:
            self.lineEdit_Rsh.setText("0")

    def calculate_nsh2_of_I(self):
        try:
            vd=float(self.lineEdit_vdrift.text())
            i=float(self.lineEdit_current.text())
            nsh2=(i*10)/(vd*1.6E-19)
            nsh2=significant_digits(nsh2,2)
            nsh2= "%.2e"%(nsh2)
            self.lineEdit_nsh2.setText(str(nsh2))
        except:
            self.lineEdit_nsh2.setText("0")

    def calculate_vd_of_I(self):
        try:
            nsh2=float(self.lineEdit_nsh2.text())
            i=float(self.lineEdit_current.text())
            vd=(i*10)/(nsh2*1.6E-19)
            vd=significant_digits(vd,2)
            vd= "%.2e"%(vd)
            self.lineEdit_vdrift.setText(str(vd))
        except:
            self.lineEdit_vdrift.setText("0")

    def calculate_I_of_I(self):
        try:
            nsh2=float(self.lineEdit_nsh2.text())
            vd=float(self.lineEdit_vdrift.text())
            i=1.6E-19*vd*nsh2/10
            i=significant_digits(i,2)
            self.lineEdit_current.setText(str(i))
        except:
            self.lineEdit_current.setText("0")

    def calculate_LG_of_fT(self):
        try:
            fT=float(self.lineEdit_fT.text())
            vt=float(self.lineEdit_vtrans.text())
            LG=1E7*vt/(2*pi*fT*1E9) # 1E7是cm单位转nm单位
            LG=significant_digits(LG,1)
            self.lineEdit_LG.setText(str(LG))
        except:
            self.lineEdit_LG.setText("0")

    def calculate_fT_of_fT(self):
        try:
            LG=float(self.lineEdit_LG.text())
            vt=float(self.lineEdit_vtrans.text())
            fT=1E7*vt/(2*pi*LG) # 1E7是cm/s单位转nm/s单位
            fT=fT/1E9
            fT=significant_digits(fT,1)
            self.lineEdit_fT.setText(str(fT))
        except:
            self.lineEdit_fT.setText("0")

    def calculate_vt_of_fT(self):
        try:
            LG=float(self.lineEdit_LG.text())
            fT=float(self.lineEdit_fT.text())
            vt=LG*2*pi*fT*1E9/1E7 # 1E7是cm单位转nm单位
            vt=significant_digits(vt,2)
            vt= "%.2e"%(vt)
            self.lineEdit_vtrans.setText(str(vt))
        except:
            self.lineEdit_vtrans.setText("0")

    def calculate_shunt_resistance(self):
        try:
            R_input=str(self.lineEdit_Rshunt.text())
            R_input=R_input.split(' ')
            sum=0
            for Rx in R_input:
                try:
                    sum+=1/float(Rx)
                except:
                    sum+=0
            R_shunt=1/sum
            R_shunt=round(R_shunt,2)
            self.Result_Rshunt.setText(str(R_shunt))
        except:
            self.Result_Rshunt.setText("0")
